﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Resources;
using Cesave.Domain.Core;
using System.Data;
using Cesave.Domain.Core.Specification;

namespace Cesave.Domain.PermisosModule.Contracts.CiclosFechas
{
	/// <summary>
	/// 
	/// </summary>
	public class CiclosFechaService
		: ICiclosFechaService
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private ICiclosFechaRepository _ciclosFechaRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="ciclosFechaRepository"></param>
		public CiclosFechaService(ICiclosFechaRepository ciclosFechaRepository)
		{
			if (ciclosFechaRepository == null)
				throw new ArgumentNullException(Messages.exception_DependenciesAreNotInitialized, "ciclosFechaRepository");
			_ciclosFechaRepository = ciclosFechaRepository;
		}

		#endregion

		#region ICiclosFechaService Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="ciclosFecha"></param>
		public void AddCiclosFecha(Entities.CiclosFecha ciclosFecha)
		{
			if (ciclosFecha == null)
				throw new ArgumentNullException(Messages.exception_InvalidArgument, "ciclosFecha");
			IUnitOfWork unitOfWork = _ciclosFechaRepository.StoreContext;
			_ciclosFechaRepository.Add(ciclosFecha);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="ciclosFecha"></param>
		public void ChangeCiclosFecha(Entities.CiclosFecha ciclosFecha)
		{
			if (ciclosFecha == null)
				throw new ArgumentNullException(Messages.exception_InvalidArgument, "ciclosFecha");
			IUnitOfWork unitOfWork = _ciclosFechaRepository.StoreContext;
			_ciclosFechaRepository.Modify(ciclosFecha);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <returns></returns>
		public List<Entities.CiclosFecha> FindCiclosFechasByJunta(Guid juntaGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			CiclosFechasByJuntaSpecification specification = new CiclosFechasByJuntaSpecification(juntaGuid);
			return _ciclosFechaRepository.GetBySpec(specification).OrderBy(f => f.Inicio).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <returns></returns>
		public List<Entities.CiclosFecha> FindCiclosFechasByJuntaAndCiclo(Guid juntaGuid, Guid cicloGuid)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			Specification<Entities.CiclosFecha> specification = new TrueSpecification<Entities.CiclosFecha>();
			specification &= new CiclosFechasByJuntaSpecification(juntaGuid);
			specification &= new CiclosFechasByCicloSpecification(cicloGuid);
			return _ciclosFechaRepository.GetBySpec(specification).OrderBy(f => f.Inicio).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="fromDate"></param>
		/// <param name="toDate"></param>
		/// <returns></returns>
		public List<Entities.CiclosFecha> FindCiclosFechasByJuntaAndDateRange(Guid juntaGuid, DateTime fromDate, DateTime toDate)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (fromDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			if (toDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			Specification<Entities.CiclosFecha> specification = new TrueSpecification<Entities.CiclosFecha>();
			specification &= new CiclosFechasByJuntaSpecification(juntaGuid);
			specification &= new CiclosFechasByDateRangeSpecification(fromDate, toDate);
			return _ciclosFechaRepository.GetBySpec(specification).OrderBy(f => f.Inicio).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="cicloGuid"></param>
		/// <param name="fromDate"></param>
		/// <param name="toDate"></param>
		/// <returns></returns>
		public List<Entities.CiclosFecha> FindCiclosFechasByCicloAndDateRange(Guid cicloGuid, DateTime fromDate, DateTime toDate)
		{
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			if (fromDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			if (toDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			Specification<Entities.CiclosFecha> specification = new TrueSpecification<Entities.CiclosFecha>();
			specification &= new CiclosFechasByCicloSpecification(cicloGuid);
			specification &= new CiclosFechasByDateRangeSpecification(fromDate, toDate);
			return _ciclosFechaRepository.GetBySpec(specification).OrderBy(f => f.Inicio).ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaGuid"></param>
		/// <param name="cicloGuid"></param>
		/// <param name="fromDate"></param>
		/// <param name="toDate"></param>
		/// <returns></returns>
		public List<Entities.CiclosFecha> FindCiclosFechasByJuntaAndCicloAndDateRange(Guid juntaGuid, Guid cicloGuid, DateTime fromDate, DateTime toDate)
		{
			if (juntaGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "juntaGuid");
			if (cicloGuid == Guid.Empty)
				throw new ArgumentException(Messages.exception_InvalidArgument, "cicloGuid");
			if (fromDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			if (toDate == DateTime.MinValue)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			CiclosFechasByCicloSpecification ciclosFechasByCicloSpecification = new CiclosFechasByCicloSpecification(cicloGuid);
			CiclosFechasByJuntaSpecification ciclosFechasByJuntaSpecification = new CiclosFechasByJuntaSpecification(juntaGuid);
			CiclosFechasByDateRangeSpecification ciclosFechasByDateRangeSpecification = new CiclosFechasByDateRangeSpecification(fromDate, toDate);
			return _ciclosFechaRepository.FindCiclosFechasByJuntaAndCicloAndDateRange(ciclosFechasByJuntaSpecification, ciclosFechasByCicloSpecification, ciclosFechasByDateRangeSpecification)
				.OrderBy(f => f.Inicio).ToList();
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_ciclosFechaRepository != null &&
				_ciclosFechaRepository.StoreContext != null)
				_ciclosFechaRepository.StoreContext.Dispose();
		}

		#endregion
	}
}